<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Console\Commands;

use Dcat\Admin\Models\Menu;
use Dcat\Admin\Models\Permission;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class GenMenuPermission extends Command
{
    protected $signature = 'admin:menu';

    protected $description = 'backup or populate menu data';

    private $backupPath = '';

    public function handle()
    {
        $type = $this->ask(
            <<<'TEXT'
    请选择操作类型:
    1:只备份
    2:只填满
    3:备份和填充
    TEXT
        );

        $this->backupPath = storage_path('menu-backup.bak');

        switch ($type) {
            case 1: // backup only
                $this->backupMenu();
                break;
            case 2: // fill only
                $this->fillMenu();
                break;
            case 3: // backup and fill
                $this->backupAndFillMenu();
                break;
            default:
                echo '请输入正确的操作类型';
                break;
        }
    }

    /**
     * backup menu.
     */
    private function backupMenu()
    {
        $res = file_put_contents($this->backupPath, serialize(optional(Menu::get())->toArray()));

        echo $res ? 'Backup succeeded' : 'Backup failed';
    }

    /**
     * fill menu.
     */
    private function fillMenu()
    {
        $menu = unserialize(file_get_contents($this->backupPath));

        $permission = $this->generatePermissions($menu);

        Menu::truncate();
        Menu::insert($menu);

        Permission::truncate();
        Permission::insert($permission);

        $permission_menu = DB::table('admin_permission_menu');
        $roles = DB::table('admin_roles');
        $roles_permission = DB::table('admin_role_permissions');
        $roles_menu = DB::table('admin_role_menu');

        $permission_menu->truncate();
        $roles->truncate();
        $roles_permission->truncate();
        $roles_menu->truncate();
        $roles->insert([
            'name' => 'Administrator',
            'slug' => 'administrator',
        ]);
        foreach ($permission as $item) {
            $permission_menu->insert([
                'permission_id' => $item['id'],
                'menu_id' => $item['id'],
            ]);
            if ($item['parent_id'] != 0) {
                $permission_menu->insert([
                    'permission_id' => $item['id'],
                    'menu_id' => $item['parent_id'],
                ]);
            }
            if ($item['parent_id'] == 0) {
                $roles_id = $roles->insertGetId([
                    'name' => $item['name'],
                    'slug' => $item['slug'],
                ]);
                $data = collect($permission)
                    ->where('parent_id', $item['id']);
                $roles_permission_data = $data->map(function ($item) use ($roles_id) {
                    return [
                        'role_id' => $roles_id,
                        'permission_id' => $item['id'],
                    ];
                })->push([
                    'role_id' => $roles_id,
                    'permission_id' => $item['id'],
                ])->toArray();
                $roles_menu_data = $data->map(function ($item) use ($roles_id) {
                    return [
                        'role_id' => $roles_id,
                        'menu_id' => $item['id'],
                    ];
                })->push([
                    'role_id' => $roles_id,
                    'menu_id' => $item['id'],
                ])->toArray();
                $roles_permission->insert($roles_permission_data);
                $roles_menu->insert($roles_menu_data);
            }
        }

        echo 'Filled successfully';
    }

    /**
     * Back up and populate the menu.
     */
    private function backupAndFillMenu()
    {
        $this->backupMenu();
        $this->fillMenu();
    }

    /**
     * Generate permission data.
     *
     * @param $menu
     *
     * @return array
     */
    private function generatePermissions($menu)
    {
        $permissions = [];
        foreach ($menu as $item) {
            $temp = [];

            $temp['id'] = $item['id'];
            $temp['name'] = $item['title'];
            $temp['slug'] = (string) Str::uuid();
            $temp['http_path'] = $this->getHttpPath($item['uri']);
            $temp['order'] = $item['order'];
            $temp['parent_id'] = $item['parent_id'];
            $temp['created_at'] = $item['created_at'];
            $temp['updated_at'] = $item['updated_at'];

            $permissions[] = $temp;
            unset($temp);
        }

        return $permissions;
    }

    /**
     * Get http path according to menu uri.
     *
     * @param $uri
     *
     * @return string
     */
    private function getHttpPath($uri)
    {
        if ($uri == '/') {
            return '';
        }

        if ($uri == '') {
            return '';
        }

        if (strpos($uri, '/') !== 0) {
            $uri = '/' . $uri;
        }

        return $uri . '*';
    }
}
